package com.damai.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class JobUtil {

	public static interface JobExecutor<T, R> {

		R execute(T data);

	}

	private static class InnerJobExecutor<T, R> implements Callable<R> {

		private T data;
		private JobExecutor<T, R> executor;

		public InnerJobExecutor(T t, JobExecutor<T, R> executor) {
			this.data = t;
			this.executor = executor;
		}

		@Override
		public R call() throws Exception {
			return executor.execute(data);
		}
	}

	public static <T, R> List<R> execute(List<T> jobs, final JobExecutor<T, R> executor, int threadCount)
			throws InterruptedException, ExecutionException {
		List<Future<R>> tmps = new ArrayList<Future<R>>(jobs.size());
		List<R> result = new ArrayList<R>();
		ExecutorService es = Executors.newFixedThreadPool(threadCount);
		for (int i = 0, c = jobs.size(); i < c; i++) {
			tmps.add(es.submit(new InnerJobExecutor<T, R>(jobs.get(i), executor)));
		}
		
		try {
			es.awaitTermination(5, TimeUnit.SECONDS); // 阻塞，直到线程池里所有任务结束

			for (Future<R> f : tmps) {
				try {
					result.add(f.get());
				} catch (ExecutionException e) {
					throw e;
				}
			}
			es.shutdown();
			return result;
		} catch (InterruptedException e) {
			throw e;
		}
	}

}
